<script setup>
import FireFilled from '@/icons/FireFilled.vue'
import TextAvatar from '@/components/text-avatar/index.vue'
const imagePrefix = import.meta.env.VITE_IMAGE_SUFFIX

const emits = defineEmits(["onClear"])

const clearHistory = () => {
  emits('onClear', true)
}
</script>
<template>
  <div class="input-box">
    <el-tooltip effect="dark" content="清空聊天记录" placement="top" v-if="showClear">
      <el-button icon="DeleteFilled" class="upload-btn" :disabled="disable" @click="clearHistory"/>
    </el-tooltip>
    <el-tooltip effect="dark" content="长文本输入" placement="top" v-if="showTools">
      <el-button icon="Document" class="upload-btn" @click="showLong = true" :disabled="showAppInput"/>
    </el-tooltip>
    <el-tooltip effect="dark" content="问题模板" placement="top" v-if="showTools">
      <el-button icon="QuestionFilled" class="upload-btn questions" @click="handleShowQuestions()"
                 :disabled="showAppInput"/>
    </el-tooltip>
    <el-tooltip effect="dark" content="应用选择" placement="top" v-if="showTools">
      <el-button icon="Menu" class="upload-btn application" @click="handleShowApp()" :disabled="showAppInput"/>
    </el-tooltip>
    <el-tooltip effect="dark" content="知识库选择" placement="top" v-if="showTools">
      <el-button icon="Reading" class="upload-btn knowledge" @click="showKnowledge(0)" :disabled="showAppInput"/>
    </el-tooltip>
    <el-tooltip effect="dark" content="资料库选择" placement="top" v-if="showTools">
      <el-button icon="Collection" class="upload-btn collection" @click="showKnowledge(1)" :disabled="showAppInput"/>
    </el-tooltip>
    <el-tooltip effect="dark" content="提问表单" placement="top"
                v-if="showTools && appInfo.id && appInfo.option_message && appInfo.option_message.length">
      <el-button icon="DocumentAdd" class="upload-btn question-form"
                 @click="handleShowAppInput"
                 :disabled="showAppInput"/>
    </el-tooltip>
    <el-input type="textarea" resize="none" show-word-limit style="width: calc(100% - 80px);"
              :placeholder="placeholder"
              :rows="2" v-model="content"
              :disabled="showAppInput" @keydown.enter="handleKeyCode($event)" maxlength="1000">
    </el-input>
    <el-tooltip effect="dark" :content="disable ? '停止回复' : '发送'" placement="top-end">
      <el-button v-if="!disable" icon="Promotion" class="send-icon" type="primary"
                 :disabled="content.trim() === '' || showAppInput" @click="handleSend"></el-button>
      <el-button v-else type="danger" icon="Remove" class="send-icon" @click="stopAnswer">
      </el-button>
    </el-tooltip>
  </div>
  <el-dialog v-model="showQuestion" class="question-dialog" :close-on-click-modal="false" append-to-body top="2vh"
             width="1000px" draggable title="问题模板" center>
    <div class="question-labels">
      <el-button v-for="item in labels" :type="item.id === label_id ? 'primary' : 'info'"
                 @click="handleSelectLabel(item.id)">{{ item.name }}
      </el-button>
    </div>
    <div style="margin-top: 16px; max-height: 70vh; overflow-y: auto; overflow-x: hidden; min-height: 180px"
         v-loading="q_loading">
      <el-row :gutter="20">
        <el-col :span="6" v-for="item in questions">
          <div class="question-item" @click="handleInputTemplate(item.template)">
            <el-tooltip effect="dark" placement="top">
              <el-text size="large" :truncated="true" style="color: #333">{{ item.title }}</el-text>
              <template #content>
                <div style="max-width: 400px">{{ item.title }}</div>
              </template>
            </el-tooltip>
            <el-tooltip effect="dark" :content="item.template" placement="top">
              <div class="question-temp">
                <div style="max-height: 54px; overflow: hidden;">{{ item.template }}</div>
              </div>
            </el-tooltip>
          </div>
        </el-col>
      </el-row>
      <el-empty description="暂无模板" v-if="questions.length === 0"/>
    </div>
    <template #footer>
      <pagination :total="total" v-model:page="page" :limit="20" :page-sizes="[20]" @pagination="getQuestions"/>
    </template>
  </el-dialog>
  <el-dialog v-model="showApplications" class="question-dialog" :close-on-click-modal="false" append-to-body top="2vh"
             width="1200px" draggable title="应用选择" center>
    <div class="app-categories">
      <el-button v-for="item in app_categories" :type="item.id === app_query.classification_id ? 'primary' : 'info'"
                 @click="handleSelectAppCategory(item.id)">{{ item.name }}
      </el-button>
    </div>
    <div
        style="margin-top: 16px; max-height: 70vh; overflow-y: auto; overflow-x: hidden; min-height: 180px"
        v-loading="app_loading"
    >
      <el-row :gutter="20">
        <el-col :span="8" v-for="item in applications">
          <div class="question-item">
            <el-row :gutter="10">
              <el-col :span="7">
                <el-image
                    :src="imagePrefix + item.avatar"
                    style="width: 90px; height: 90px; border-radius: 4px; margin: 5px 0 0 5px"
                >
                  <template #error>
                    <text-avatar :text="item.title" :width="90"/>
                  </template>
                </el-image>
              </el-col>
              <el-col :span="17">
                <div @click="handleSelectApp(item)">
                  <el-tooltip effect="dark" :content="item.title" placement="top">
                    <el-text size="large" :truncated="true" style="color: var(--el-text-color-primary)">
                      {{ item.title }}
                    </el-text>
                  </el-tooltip>
                  <el-tooltip effect="dark" placement="top">
                    <template #content>
                      <div style="max-width: 400px">{{ item.introduction }}</div>
                    </template>
                    <div class="question-temp">
                      <div class="multi-line-text line-clamp-2"
                           style="max-height: 36px;"
                      >{{ item.introduction }}
                      </div>
                    </div>
                  </el-tooltip>
                  <div class="flex h-30 align-items-center" v-if="app_query.classification_id !== -1 && !app_loading">
                    <el-icon class="font-size-l" style="color: var(--el-color-danger)">
                      <FireFilled/>
                    </el-icon>
                    <span class="margin-left-5 margin-right-30 line-height margin-top-2">{{ item.click_number }}</span>
                    <el-tooltip effect="dark" content="收藏" placement="top" v-if="!item.is_collect">
                      <el-icon class="font-size-xl" @click.stop="likeApp(item)">
                        <component is="Star"/>
                      </el-icon>
                    </el-tooltip>
                    <el-tooltip effect="dark" content="取消收藏" placement="top" v-else>
                      <el-icon class="font-size-3xl" style="color: var(--el-color-danger)" @click.stop="likeApp(item)">
                        <component is="StarFilled"/>
                      </el-icon>
                    </el-tooltip>
                  </div>
                </div>
              </el-col>
            </el-row>
          </div>
        </el-col>
      </el-row>
      <el-empty description="暂无应用" v-if="applications.length === 0"/>
    </div>
    <template #footer>
      <pagination :total="app_total" v-model:page="app_query.page" :limit="20" :page-sizes="[20]"
                  @pagination="getAppList"/>
    </template>
  </el-dialog>
  <el-dialog v-model="showLong" :close-on-click-modal="false" append-to-body draggable title="长文本输入" center>
    <el-input type="textarea" v-model="content" :rows="10" maxlength="3000" show-word-limit clearable
              :placeholder="placeholder" @keydown.enter="handleKeyCode($event)"/>
    <template #footer>
      <el-button type="primary" @click="handleSend()" :disabled="content.trim() === '' || disable">发送</el-button>
      <el-button type="warning" @click="showLong = false">取 消</el-button>
    </template>
  </el-dialog>
</template>
<script>
import {httpTemplateList, httpLabelList} from '@/api/templates.js'
import {httpAppCategories, httpAppList, httpCollectApp} from '@/api/application.js'
import Pagination from '@/components/pagination/index.vue'
import useAppStorage from '@/stores/application.js'

const appStore = useAppStorage()
export default {
  components: {Pagination},
  props: {
    disable: {
      type: Boolean,
      default: false
    },
    appInfo: {
      type: Object,
      default: () => {
        return {
          id: 0
        }
      }
    },
    showTools: {
      type: Boolean,
      default: true
    },
    knowledgeId: Number,
    onSubmit: {
      type: Function,
      default: () => {
      }
    },
    fileId: String,
    handleShowAppInput: {
      type: Function,
      default: () => {
      }
    },
    showAppInput: {
      type: Boolean,
      default: false
    },
    defaultFiles: {
      type: Array,
      default: () => {
        return []
      }
    },
    stopAnswer: {
      type: Function,
      default: () => {
      }
    },
    fileUpdate: {
      type: Function,
      default: () => {
      }
    },
    selectApp: {
      type: Function,
      default: () => {
      }
    },
    showKnowledge: {
      type: Function,
      default: () => {
      }
    },
    showClear: {
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String,
      default: "提出您希望助手为您完成事情，如:撰写、生成、总结、回答，答案、方案、文本等。（Enter = 发送，Shift+Enter = 换行）"
    }
  },
  data() {
    return {
      content: '',
      acceptFiles: [
        '.pdf', '.docx', '.xlsx', '.pptx', '.png', '.jpg', '.jpeg', '.txt',
        '.html', '.md', '.json', '.csv', '.xml', '.msg', '.py'
      ],
      upload_files: [],
      showLong: false,
      showQuestion: false,
      label_id: 0,
      labels: [],
      questions: [],
      page: 1,
      total: 0,
      q_loading: false,
      tempInit: false,
      appInit: false,
      showApplications: false,
      applications: [],
      app_categories: [],
      appStore,
      app_query: {
        page: 1,
        limit: 20,
        classification_id: 0,
        is_owner: 0,
        keyword: ''
      },
      app_total: 0,
      app_loading: false,
      likeTimer: null,
    }
  },
  methods: {
    handleShowApp() {
      if (!this.appInit) {
        this.appInit = true
        this.applications = []
        this.app_query.classification_id = 0
        this.app_query.keyword = ''
        this.handleAppFilter()
        this.getAppCategories()
      }
      this.showApplications = true
    },
    likeApp(item) {
      if (this.likeTimer) {
        clearTimeout(this.likeTimer)
      }
      this.likeTimer = setTimeout(() => {
        item.is_collect = item.is_collect === 0 ? 1 : 0
        httpCollectApp(item.id).catch(() => {
          item.is_collect = item.is_collect === 0 ? 1 : 0
        })
        this.likeTimer = null
      }, 500)
    },
    handleAppFilter() {
      this.app_query.page = 1
      this.getAppList()
    },
    async getAppList() {
      this.app_loading = true
      const query = {...this.app_query}
      if (query.classification_id < 0) {
        query.classification_id = 0
      }
      const res = await httpAppList(query).catch(() => null)
      this.app_loading = false
      if (!res) return
      const {list, total} = res
      this.app_total = total
      this.applications = list
    },
    async getAppCategories() {
      const res = await httpAppCategories({limit: 99}).catch(() => null)
      if (!res) return
      const {list} = res
      this.app_categories = [
        {id: 0, name: '全部'},
        {id: -1, name: '我的应用'},
        {id: -2, name: '收藏应用'},
      ].concat(list)
    },
    handleSelectAppCategory(id) {
      if (id === this.app_query.classification_id) {
        return
      }
      if (id === -1 || id === -2) {
        this.app_query.is_owner = Math.abs(id)
      } else {
        this.app_query.is_owner = 0
      }
      this.app_query.classification_id = id
      this.handleAppFilter()
    },
    handleSelectApp(app) {
      this.showApplications = false
      const appCopy = {...app}
      appCopy.option_message = JSON.parse(appCopy.option_message)
      this.selectApp(appCopy)
    },
    handleInputTemplate(content) {
      this.content = content
      this.showQuestion = false
    },
    getLabels() {
      httpLabelList().then(({list}) => {
        this.labels = [{
          id: 0,
          name: '全部',
          created_at: ''
        }].concat(list)
      }).catch(() => {
      })
    },
    handleSelectLabel(id) {
      if (id === this.label_id) {
        return
      }
      this.label_id = id
      this.page = 1
      this.getQuestions()
    },
    handleShowQuestions() {
      if (!this.tempInit) {
        this.label_id = 0
        this.questions = []
        this.page = 1
        this.getQuestions()
        this.tempInit = true
      }
      this.showQuestion = true
    },
    getQuestions() {
      this.q_loading = true
      httpTemplateList({
        label_id: this.label_id,
        knowledge_id: this.knowledgeId,
        page: this.page
      }).then(({list, total}) => {
        this.q_loading = false
        this.questions = list
        this.total = total
      }).catch(() => {
        this.q_loading = false
      })
    },
    handleKeyCode(e) {
      if (e.keyCode === 13) {
        if (!e.shiftKey) {
          e.preventDefault()
          this.handleSend()
        }
      }
    },
    handleSend() {
      if (this.disable) {
        return
      }
      if (this.content.trim() === "") {
        this.content = ""
        return
      }
      this.showLong = false
      this.onSubmit(this.content)
      this.content = ""
    }
  },
  mounted() {
    this.upload_files = this.defaultFiles
    this.getLabels()
  },
  watch: {
    'upload_files'(value) {
      this.fileUpdate(value)
    },
    'defaultFiles'(value) {
      this.upload_files = value
    },
    'knowledgeId'() {
      this.tempInit = false
      this.appInit = false
    },
    'appStore.show'(value) {
      if (value) {
        this.handleShowApp()
      }
    },
    'showApplications'(value) {
      if (!value) {
        appStore.setShow(false)
      }
    }
  }
}
</script>
<style scoped lang="scss">
.input-box {
  width: calc(100% - 40px);
  max-height: 94px;
  position: absolute;
  bottom: 0;
  left: 20px;

  .send-icon {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 60px;
    height: 100%;
    font-size: 25px;
  }

  .upload-btn {
    position: absolute;
    left: 0;
    top: -38px;
    width: 40px;
    height: 30px;
    font-size: 20px;
    z-index: 1;
    margin-left: 0;

    &.questions {
      left: 52px;
    }

    &.application {
      left: 104px;
    }

    &.knowledge {
      left: 156px;
    }

    &.collection {
      left: 208px;
    }

    &.question-form {
      left: 260px;
    }
  }

  .chat-upload-box {
    position: absolute;
    top: -28px;
    left: 0;
    width: 100%;
  }
}

.question-item {
  background: var(--el-bg-color);
  box-shadow: var(--el-box-shadow-light);
  padding: 16px;
  border-radius: 5px;
  margin-bottom: 20px;
  cursor: pointer;

  .question-temp {
    line-height: 18px;
    font-size: 13px;
    height: 36px;
    display: flex;
    align-items: center;
    color: var(--el-text-color-regular);
  }
}
</style>
<style lang="scss">
.chat-upload-box {
  .el-upload-list {
    top: -20px;
    font-size: 12px;
    margin: 0;
  }

  .el-upload-list__item {
    float: left;
    width: 50%;

    .el-progress {
      opacity: 0;
      display: none;
    }
  }
}

.question-dialog {
  background: var(--el-bg-color-page);
}
</style>